﻿using System;
using System.Collections.Generic;
using System.Linq;
using Cos.Core.Model.Security;
using log4net;

namespace Cos.Core.Module.Service
{
    public class ModuleService : IModuleService
    {
        protected ILog Logger = LogManager.GetLogger(typeof(ModuleService));
        private List<IModule> _modules;

        public IEnumerable<IModule> GetPlugins()
        {
            if (_modules == null)
            {
                LoadPlugins();
            }
            return _modules;
        }

        public IEnumerable<IModule> GetAvailablePlugins(User user)
        {
            if (_modules == null)
            {
                LoadPlugins();
            }

            var availablePlugins = new List<IModule>();

            // Check from the list of plugin which the user are access
            foreach (var plugin in _modules)
            {

                // Check if the UI module
                if (!plugin.IsUiModule)
                {
                    Logger.Info("Found plugin: " + plugin.InternalName + " but it is not a UI module");
                    continue;
                }

                availablePlugins.Add(plugin);

                // // Use has a full control permission.
                // if (user.getRoles().contains(User.Role.ADMIN)) {
                // availablePlugins.add(plugin);
                // } else {
                // // Does the user have access to at least one method in the actions of the plugin
                // boolean found = false;
                // List<Class<?>> pluginActions = plugin.getJsonActions();
                // if (pluginActions != null) {
                // for (Class<?> pluginAction : pluginActions) {
                // if (pluginAction.isAnnotationPresent(CosJsonAction.class)) {
                // Method[] pluginMethods = pluginAction.getMethods();
                // for (Method pluginMethod : pluginMethods) {
                // if (pluginMethod.isAnnotationPresent(CosJsonMethod.class) && Authorization.isAuthorized(pluginMethod,
                // CosContext.getUser())) {
                // availablePlugins.add(plugin);
                // found = true;
                // break;
                // }
                // }
                // }
                // if (found) {
                // break;
                // }
                // }
                // }
                // }
            }

            return availablePlugins;
        }

        public void InitPlugins()
        {
            if (_modules == null)
            {
                LoadPlugins();
            }

            var locPlugins = GetPlugins();

            if (!locPlugins.Any() && Logger.IsInfoEnabled)
            {
                Logger.Info("No plugins were found.");
            }

            foreach (var cosPlugin in locPlugins)
            {
                if (Logger.IsInfoEnabled)
                {
                    Logger.Info("Found plugin: " + cosPlugin.InternalName + " : " + cosPlugin.GetType().AssemblyQualifiedName);
                }

                cosPlugin.Init();
            }
        }

        public void LoadPlugins()
        {
            throw new NotImplementedException();
            //plugins = new ArrayList<CosModule>();

            //for (CosModule cosPlugin : ServiceLocator.getApplicationContext().getBeansOfType(CosModule.class).values()) {
            //    plugins.add(cosPlugin);
        }

    }
}